package com.gitee.liuzhi.framework.starter.utils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by 2022/5/6/0006
 *
 * @author LiuZhi
 * @version V1.0
 * @description: 基于 ConcurrentHashMap 的本地缓存工具类, 缓存删除基于 ScheduledExecutorService 定时器
 */
public class LocalCacheUtils {

    /**
     * 默认大小
     */
    private static final int DEFAULT_CAPACITY = 1024;

    /**
     * 最大缓存大小
     */
    private static final int MAX_CAPACITY = 10000;

    /**
     * 默认缓存过期时间(秒)
     */
    private static final long DEFAULT_TIMEOUT = 30;

    /**
     * 存储缓存的 Map
     */
    private static final ConcurrentHashMap<String, Object> LOCAL_CACHE;

    /**
     * 清除缓存的定时器
     */
    private static final ScheduledExecutorService SCHEDULED_EXECUTOR;

    static {
        LOCAL_CACHE = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
        SCHEDULED_EXECUTOR = Executors.newScheduledThreadPool(3);
    }

    private LocalCacheUtils() {
    }

    /**
     * 缓存任务清除类
     */
    static class ClearTask implements Runnable {

        private final String key;

        public ClearTask(String key) {
            this.key = key;
        }

        @Override
        public void run() {
            LocalCacheUtils.remove(key);
        }

    }

    /**
     * 添加缓存
     */
    public static boolean put(String key, Object object) {
        if (checkCapacity()) {
            LOCAL_CACHE.put(key, object);
            SCHEDULED_EXECUTOR.schedule(new ClearTask(key), DEFAULT_TIMEOUT, TimeUnit.SECONDS);
            return true;
        }
        return false;
    }

    /**
     * 添加缓存(秒)
     */
    public static boolean put(String key, Object object, int timeOut) {
        if (checkCapacity()) {
            LOCAL_CACHE.put(key, object);
            SCHEDULED_EXECUTOR.schedule(new ClearTask(key), timeOut, TimeUnit.SECONDS);
            return true;
        }
        return false;
    }

    /**
     * 批量增加缓存(秒)
     */
    public static boolean put(Map<String, Object> m, int timeOut) {
        if (LOCAL_CACHE.size() + m.size() <= MAX_CAPACITY) {
            LOCAL_CACHE.putAll(m);
            for (String key : m.keySet()) {
                SCHEDULED_EXECUTOR.schedule(new ClearTask(key), timeOut, TimeUnit.SECONDS);
            }
            return true;
        }
        return false;
    }

    /**
     * 判断容量大小
     */
    public static boolean checkCapacity() {
        return LOCAL_CACHE.size() < MAX_CAPACITY;
    }

    /**
     * 清除所有缓存
     */
    public void clearAll() {
        if (LOCAL_CACHE.size() > 0) {
            LOCAL_CACHE.clear();
        }
        // SCHEDULED_EXECUTOR.shutdown();
    }

    /**
     * 删除缓存
     */
    public static void remove(String key) {
        LOCAL_CACHE.remove(key);
    }

    /**
     * 获取缓存
     */
    public static Object get(String key) {
        return LOCAL_CACHE.get(key);
    }

    /**
     * 是否包含某个缓存
     */
    public static boolean isContain(String key) {
        return LOCAL_CACHE.contains(key);
    }


}
